package swimv2gm.bl.session;

import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import org.jboss.ejb3.annotation.RemoteBinding;

import swimv2gm.bl.domain.Ability;
import swimv2gm.bl.domain.User;
import swimv2gm.bl.util.UserData;
import swimv2gm.bl.util.Utilities;

/**
 * Implementazione del gestore competenze.
 * 
 * @author Matteo Gallesio
 */
@Stateless
@RemoteBinding(jndiBinding = "AbilityManager")
public class AbilityManagerBean implements AbilityManager {
	@PersistenceContext(unitName = "swimv2")
	private EntityManager manager;

	/**
	 * {@inheritDoc}
	 */
	@Override
	public long createAbility(String nome,String descrizione) throws ExistingDataException {
		Ability a = new Ability();

		// required fields not empty
		if (!Utilities.validate(nome,Utilities.REQUIRED) || !Utilities.validate(descrizione,Utilities.REQUIRED)) {
			return -1;
		}

		// don't repeat ability names
		Query q = manager.createQuery("from competenze c where c.nome=:nome");
		q.setParameter("nome",nome);
		List<Object> o = q.getResultList();
		if (o == null || o.size() > 0) {
			throw new ExistingDataException();
		}

		a.setNome(nome);
		a.setDescrizione(descrizione);

		try {
			manager.persist(a);
		} catch (PersistenceException e) {
			return -1;
		}

		return a.getId();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean editAbility(long cid,String nome,String descrizione) throws ExistingDataException {
		// required fields not empty
		if (!Utilities.validate(nome,Utilities.REQUIRED) || !Utilities.validate(descrizione,Utilities.REQUIRED)) {
			return false;
		}
		Ability a = manager.find(Ability.class,cid);
		if (a == null)
			return false;

		// don't repeat ability names
		Query q = manager.createQuery("from competenze c where c.nome=:nome");
		q.setParameter("nome",nome);
		List<Ability> as = q.getResultList();
		if (as != null && as.size() > 0 && as.get(0).getId() != cid) {
			throw new ExistingDataException();
		}

		a.setNome(nome);
		a.setDescrizione(descrizione);

		manager.flush();
		return true;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Ability getAbility(long cid) {
		return manager.find(Ability.class,cid);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Ability> getAll() {
		Query q = manager.createQuery("from competenze c order by c.nome");
		List<Ability> fullList = q.getResultList();
		return fullList;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<Ability> getNotDeclaredBy(long uid) {
		User u = manager.find(User.class,uid);

		if (u == null)
			return null;

		List<Ability> all = getAll();
		all.removeAll(u.getCompetenze());
		return all;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public List<UserData> getUserData(long cid) {
		Query q = manager
				.createQuery("select new swimv2gm.bl.util.UserData(u.uid,u.nome,u.cognome) from competenze c, in (c.utenti) u where c.cid=:cid order by u.cognome");
		q.setParameter("cid",cid);

		List<UserData> users = q.getResultList();
		return users;
	}
}
